using System;
using System.Collections.Generic;
using System.Text;

namespace RapidHDL
{
    public class MyHardware : RapidHardware
    {
        public override bool ConfigureSettings()
        {
            Settings.UseStart = false;
            Settings.BuildHardware = false;
            Settings.ForceBuildHardware = false;
            Settings.RunFromXilinx = true;
            Settings.ClockFrequency = 1;
            Settings.UseSDRAM = true;
            Settings.BuildRemote = false;
            return true;
        }

        public override bool GenerateStructure(TopLevelComponent TopLevelComponent)
        {
            /* Up Counter */
            //UpCounter oUpCounter = new UpCounter(TopLevelComponent, "counter", TopLevelComponent.MainClock,17, true, true, 0,16000 , 1);
            UpCounter oUpCounter = new UpCounter(TopLevelComponent, "counter", TopLevelComponent.MainClock, 14, true, true, 0, 20, 2);
            SystemInterface.AddSignalSource("enable", oUpCounter.EnableIn, 1);
            oUpCounter.ResetIn.Connection = TopLevelComponent.MainReset;

            TopLevelComponent.TestBusWrite.ConnectSubset(0, 0, oUpCounter.CountOut, 4, 4);
            TopLevelComponent.TestBusWrite.ConnectSubset(1, 12, Operators.CONST(TopLevelComponent, 0, 12), 0, 11);
            //Utility.SourceExtraBits(TopLevelComponent, TopLevelComponent.TestBusWrite, 0);
            

            /* State machine*/
            /*
            StateMachine oStateMachine = new StateMachine(TopLevelComponent, "state_machine", TopLevelComponent.MainClock);
            oStateMachine.ResetIn.Connection = TopLevelComponent.MainReset;

            NodeVector nvGo = new NodeVector(TopLevelComponent, "GO_I", 1);
            NodeVector nvFinish = new NodeVector(TopLevelComponent, "FINISH_I", 1);

            SystemInterface.AddSignalSource("Go", nvGo, 1);
            SystemInterface.AddSignalSource("Finish", nvFinish, 0);            

            oStateMachine.AddState("state_a");
            oStateMachine.AddState("state_b");
            oStateMachine.AddState("state_c");
            oStateMachine.AddState("state_d");
            oStateMachine.AddState("state_e");

            oStateMachine.SetDefaultState("state_a");

            oStateMachine.StateTransition("state_a", nvGo, "state_b");
            oStateMachine.StateTransition("state_b", "state_c");
            oStateMachine.StateTransition("state_c", Operators.NOT(TopLevelComponent,nvFinish), "state_e");
            oStateMachine.StateTransition("state_c", nvFinish, "state_d");
            oStateMachine.StateTransition("state_d", "state_a");
            oStateMachine.StateTransition("state_e", "state_b");
            */

            //tests go here...

            //Constant oConst = new Constant(TopLevelComponent, "ca", 3, 1);
            //AssignmentMux oAMux = new AssignmentMux(TopLevelComponent, "amux_test", 3,oConst.OutputNodes);
            //Simulation.AddComponentTest("", "amux_test");

            //ResetReg oReg = new ResetReg(TopLevelComponent, "reg", TopLevelComponent.MainClock, 3, true, false, false);
            //Simulation.AddComponentTest("", "reg");

            return true;
        }

        public override bool ConfigureSignalViews(TopLevelComponent TopLevelComponent)
        {
            //SystemInterface.AddSignalView("counter.RESET_I");
            //SystemInterface.AddSignalView("counter.ENABLE_I");

            //SystemInterface.AddSignalView(".TEST_BUS_READ_I");

            /*SystemInterface.AddSignalView("counter.reset_to.and0.Out");
            SystemInterface.AddSignalView("counter.adder.InA");
            SystemInterface.AddSignalView("counter.adder.InB");
            SystemInterface.AddSignalView("counter.adder.Out");*/
            SystemInterface.AddSignalView("count","counter.COUNT_O");
            SystemInterface.FormatSignalView("count",SignalFormat.Unsigned);
            

            if (!Settings.RunFromXilinx)
            {
                //SystemInterface.AddSignalView("counter.RESET_I");
                //SystemInterface.AddSignalView("counter.reset_or.In");
            }
            /*
            SystemInterface.AddSignalView("counter.reset_or.Out");

            SystemInterface.AddSignalView("counter.compare_limit.InA");
            SystemInterface.AddSignalView("counter.compare_limit.InB");
            SystemInterface.AddSignalView("counter.compare_limit.Out");

            SystemInterface.AddSignalView("state_machine.current_state.DATA_O");
            */

            //Simulation.SetComponentTrace("counter.adder", "output");
            //Simulation.SetComponentTrace("counter.count_by", "output");
            //oRapidHardware.Simulation.SetComponentTrace("counter.count_reg", "output");
            //oRapidHardware.Simulation.SetNodeVectorTrace("counter.adder.Out", "stabilize");

            return true;
        }
    }
}
